package com.sjx.jtt809.business;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.sjx.jtt809.business.impl.ResponseHandlerImpl_0x1001;
import com.sjx.jtt809.business.impl.ResponseHandlerImpl_0x1005;
import com.sjx.jtt809.business.impl.ResponseHandlerImpl_0x1202;
import com.sjx.jtt809.business.impl.ResponseHandlerImpl_0x9002;
import com.sjx.jtt809.pojo.BusinessBean;
import com.sjx.jtt809.pojo.Response;
import com.sjx.jtt809.pojo.command.ResponseJtt809_0x1200_VehiclePackage;
import com.sjx.jtt809.util.ConstantJtt809Util;
import io.netty.channel.ChannelHandlerContext;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 业务工厂，实例化业务
 */
public class BusinessFactory implements Runnable {

    private static final Log logger = LogFactory.get();

    /**
     * 创建队列
     */
    private static final BlockingQueue<BusinessBean> QUEUE = new ArrayBlockingQueue<BusinessBean>(50);

    /**
     * 业务实现方法类
     */
    public static Map<Integer, Class<? extends IBusinessServer>> businessMap = new HashMap<Integer, Class<? extends IBusinessServer>>();

    static {
        /**
         * 收到：主链路登录请求消息（0x1001）
         * 响应：主链路登录应答消息（0x1002）
         */
        businessMap.put(ConstantJtt809Util.UP_CONNECT_REQ, ResponseHandlerImpl_0x1001.class);

        /**
         * 收到：主链路连接保持请求消息（0x1005）
         * 响应：主链路连接保持应答消息（0x1006）
         */
        businessMap.put(ConstantJtt809Util.UP_LINKETEST_REQ, ResponseHandlerImpl_0x1005.class);

        /**
         * 收到：从链路连接应答信息（0x9002）
         */
        businessMap.put(ConstantJtt809Util.DOWN_CONNECT_RSP, ResponseHandlerImpl_0x9002.class);

        /**
         * 收到：实时上传车辆定位信息消息（0x1202）
         * 响应：接收车辆定位信息数量通知消息（达到一定量时发送通知）
         */
        businessMap.put(ConstantJtt809Util.UP_EXG_MSG_REAL_LOCATION, ResponseHandlerImpl_0x1202.class);
    }

    /**
     * 有数据时直接从队列的队首取走，无数据时阻塞，在millis秒内有数据，取走，超过millis秒还没数据，返回失败
     *
     * @param millis
     * @return
     * @throws InterruptedException
     */
    public static BusinessBean waitFor(long millis) throws InterruptedException {
        return QUEUE.poll(millis, TimeUnit.MILLISECONDS);
    }

    /**
     * 设定的等待时间为1s，如果超过1s还没加进去返回false
     *
     * @param businessBean
     * @throws InterruptedException
     */
    public static boolean goOn(BusinessBean businessBean) throws InterruptedException {
        return QUEUE.offer(businessBean, 1000, TimeUnit.MILLISECONDS);
    }

    public void run() {
        try {
            while (true) {
                logger.info("================> 【信息|队列】剩余：{}", QUEUE.size());
                Thread.sleep(1500);
                BusinessBean businessBean = waitFor(3000);

                if (businessBean == null) {
                    continue;
                }

                Response msg = businessBean.getResponse();
                ChannelHandlerContext ctx = businessBean.getCtx();

                Class<? extends IBusinessServer> cls = null;

                switch (msg.getMsgId()) {
                    case ConstantJtt809Util.UP_EXG_MSG:
                        // 获取子业务类型
                        if (msg instanceof ResponseJtt809_0x1200_VehiclePackage) {
                            ResponseJtt809_0x1200_VehiclePackage responseJtt8090x1200VehiclePackage = (ResponseJtt809_0x1200_VehiclePackage) msg;
                            cls = businessMap.get(responseJtt8090x1200VehiclePackage.getDataType());
                        }
                        break;
                    default:
                        cls = businessMap.get(msg.getMsgId());
                }


                // 未找到实现方法则返回
                if (cls == null) {
                    return;
                }

                // 实例化类
                IBusinessServer iBusinessServer = cls.newInstance();
                // 执行业务方法
                iBusinessServer.businessHandler(ctx, msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
